package me.zhengjie.modules.finace_taxation.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import me.zhengjie.base.PageInfo;
import me.zhengjie.base.QueryHelpMybatisPlus;
import me.zhengjie.modules.finace_taxation.domain.FtServiceProcess;
import me.zhengjie.modules.finace_taxation.domain.FtServiceType;
import me.zhengjie.modules.finace_taxation.service.dto.*;
import me.zhengjie.modules.finace_taxation.domain.FtServiceVO;
import me.zhengjie.utils.ConvertUtil;
import me.zhengjie.utils.FileUtil;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.modules.finace_taxation.domain.FtService;
import me.zhengjie.modules.finace_taxation.service.FtServiceService;
import me.zhengjie.modules.finace_taxation.service.mapper.FtServiceMapper;
import me.zhengjie.utils.RedisUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
// 默认不使用缓存
//import org.springframework.cache.annotation.CacheConfig;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
* @author 杨荣森
* @date 2021-06-23
*/
@Service
@AllArgsConstructor
// @CacheConfig(cacheNames = FtServiceService.CACHE_KEY)
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class FtServiceServiceImpl implements FtServiceService {

    // private final RedisUtils redisUtils;
    private final FtServiceMapper ftServiceMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public PageInfo<FtServiceVO> queryAll(Map<String,Object> map, Pageable pageable) {
        IPage<FtServiceDto> queryPage = PageUtil.toMybatisPage(pageable);
        IPage<FtServiceDto> page = ftServiceMapper.getServices(queryPage, map);
        List<FtServiceDto> list = page.getRecords();
        PageInfo<FtServiceVO> ftServiceVO = ConvertUtil.convertPage(page, FtServiceVO.class);
        for (int i=0;i<list.size();i++) {
            List<String> strings = Arrays.asList(list.get(i).getCoverImg().split(","));
            ftServiceVO.getContent().get(i).setCoverImg(strings);
            if(list.get(i).getActivityName() == null){
                ftServiceVO.getContent().get(i).setActivityName("暂无活动");
            }
            ftServiceVO.getContent().get(i).setServiceProcessVOS(ftServiceMapper.getServiceProcessById(list.get(i).getId()));
        }
        return ftServiceVO;
    }

    @Override
    public List<FtServiceDto> queryAll(FtServiceQueryParam query){
        List<FtServiceDto> ftServiceDtos = ftServiceMapper.getServicesDownLoad(query);
        return ftServiceDtos;
    }

    @Override
    public FtService getById(String id) {
        return ftServiceMapper.selectById(id);
    }

    @Override
    // @Cacheable(key = "'id:' + #p0")
    public FtServiceDto findById(String id) {
        return ConvertUtil.convert(getById(id), FtServiceDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(FtServiceDto resources) {
        FtService entity = ConvertUtil.convert(resources, FtService.class);
        List<String> strings = new ArrayList<>();
        List<FtServiceProcess> processList = resources.getServiceProcessVOS();
        for (int i = 0;i<processList.size();i++){
            strings.add(processList.get(i).getName());
        }
        int insertServiceFlag = ftServiceMapper.insert(entity);
        if (insertServiceFlag > 0){
            ftServiceMapper.insertServiceProcess(strings,entity.getId());
            if (resources.getLimitDate() != 0){
                redisUtils.set(entity.getId(),resources.getLimitDate(),resources.getLimitDate()*24*60*60);
            }
        }
        return insertServiceFlag;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateById(FtServiceDto resources){
        StringBuilder stringBuilder = new StringBuilder();
        String coverImg = StringUtils.strip(resources.getCoverImg(),"[]");
        String[] strings = coverImg.split(",");
        for (int i = 0;i<strings.length;i++){
            stringBuilder.append(strings[i].toString().replace("\"",""));
            if(i<strings.length-1){
                stringBuilder.append(",");
            }
        }
        resources.setCoverImg(stringBuilder.toString());
        FtService entity = ConvertUtil.convert(resources, FtService.class);
        int ret = ftServiceMapper.updateById(entity);
        if(resources.getServiceProcessVOS() != null){
            //删除服务得流程再添加
            ftServiceMapper.delServiceProcess(resources.getId());
            List<String> stringList = new ArrayList<>();
            List<FtServiceProcess> processList = resources.getServiceProcessVOS();
            for (int i = 0;i<processList.size();i++){
                stringList.add(processList.get(i).getName());
            }
            if (stringList.size() > 0){
                ftServiceMapper.insertServiceProcess(stringList,resources.getId());
            }
        }
        if (resources.getActivityFlag().equals("1")){
            redisUtils.set(resources.getId(),resources.getLimitDate(),resources.getLimitDate()*24*60*60);
        }else {
            redisUtils.del(resources.getId());
        }
        // delCaches(resources.id);
        return ret;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeByIds(Set<String> ids){
        // delCaches(ids);
        Iterator iterator = ids.iterator();
        String serviceId = (String) iterator.next();
        boolean redisFlag = redisUtils.hasKey(serviceId);
        if (redisFlag){
            redisUtils.del(serviceId);
        }
        return ftServiceMapper.deleteBatchIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int putShelfService(FtService ftService) {
        return ftServiceMapper.updateById(ftService);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int popularService(FtService ftService) {
        return ftServiceMapper.updateById(ftService);
    }

    @Override
    public List<FtServiceVO> getPutShelfServicesByType(Map<String,Object> map) {
        int pageNo = Integer.parseInt(map.get("pageNo").toString());
        int pageSize = Integer.parseInt(map.get("pageSize").toString());
        Page<FtServiceVO> page = new Page<>(pageNo,pageSize);
        List<FtServiceDto> ftServiceDtos = ftServiceMapper.getPutShelfServicesByType(page,map);
        List<FtServiceVO> ftServiceVOS = new ArrayList<>();
        for (int i=0;i<ftServiceDtos.size();i++) {
            FtServiceVO ftServiceVO = new FtServiceVO();
            FtServiceDto ftServiceDto = ftServiceDtos.get(i);
            BeanUtils.copyProperties(ftServiceDto,ftServiceVO);
            List<String> strings = Arrays.asList(ftServiceDtos.get(i).getCoverImg().split(","));
            ftServiceVO.setCoverImg(strings);
            ftServiceVOS.add(ftServiceVO);
        }
        return ftServiceVOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int serviceFavorite(FtServiceFacoriteDto ftServiceFacoriteDto) {
        return ftServiceMapper.serviceFavorite(ftServiceFacoriteDto);
    }

    @Override
    public int getServiceFavoriteCount(String userId, String serviceId) {
        return ftServiceMapper.getServiceFavoriteCount(userId, serviceId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int cacelServiceFavorite(String userId, String serviceId) {
        return ftServiceMapper.cacelServiceFavorite(userId, serviceId);
    }

    @Override
    public List<FtServiceProcess> getServiceProcess(String serviceId) {
        return ftServiceMapper.getServiceProcessById(serviceId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addServiceAdvisoryNumber(String serviceId) {
        return ftServiceMapper.addServiceAdvisoryNumber(serviceId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addServiceBrowseNumber(String serviceId) {
        return ftServiceMapper.addServiceBrowseNumber(serviceId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeById(String id){
        Set<String> set = new HashSet<>(1);
        set.add(id);
        return this.removeByIds(set);
    }

    @Override
    public PageInfo<FtService> queryServiceByUserId(Map<String, Object> map) {
        int pageNo = Integer.parseInt(map.get("pageNo").toString());
        int pageSize = Integer.parseInt(map.get("pageSize").toString());
        Page<FtService> page = new Page<>(pageNo, pageSize);
        IPage<FtService> pageInfo= ftServiceMapper.queryServiceByUserId(page, map);
//        PageInfo<FtService> pageInfo = new PageInfo<>();
//        pageInfo.setTotalElements(page.getTotal());
//        pageInfo.setContent(ftIndustryDetailsList);
        return ConvertUtil.convertPage(pageInfo, FtService.class);
    }

    @Override
    public List<FtService> searchByType(Map<String, Object> map) {
        QueryWrapper<FtService> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(FtService::getType, map.get("type").toString());
        List<FtService> list = ftServiceMapper.selectList(wrapper);
        return list;
    }

    @Override
    public FtLimitDateDto getLimitDateByServiceId(String serviceId) {
        boolean keyFlag = redisUtils.hasKey(serviceId);
        FtLimitDateDto ftLimitDateDto = new FtLimitDateDto();
        if (keyFlag){
            int time = (int) redisUtils.getExpire(serviceId);
            int day = time/(60*60*24);
            int hour = (time - (60*60*24* day))/3600;
            int minute = (time - 60*60*24* day - 3600 * hour)/60;
            int second = time - 60*60*24* day - 3600 * hour - 60*minute;
            ftLimitDateDto.setDay(day);
            ftLimitDateDto.setHour(hour);
            ftLimitDateDto.setMinute(minute);
            ftLimitDateDto.setSecond(second);
            return ftLimitDateDto;
        }else {
            ftLimitDateDto.setDay(0);
            ftLimitDateDto.setHour(0);
            ftLimitDateDto.setMinute(0);
            ftLimitDateDto.setSecond(0);
            return ftLimitDateDto;
        }
    }

    /*
    private void delCaches(String id) {
        redisUtils.delByKey(CACHE_KEY + "::id:", id);
    }

    private void delCaches(Set<String> ids) {
        for (String id: ids) {
            delCaches(id);
        }
    }*/

    @Override
    public void download(List<FtServiceDto> all, HttpServletResponse response) throws IOException {
      List<Map<String, Object>> list = new ArrayList<>();
      for (FtServiceDto ftService : all) {
        Map<String,Object> map = new LinkedHashMap<>();
              map.put("服务标题", ftService.getTitle());
              map.put("封面地址", ftService.getCoverImg());
              map.put("服务介绍", ftService.getIntroduction());
              map.put("原价", ftService.getOldPrice());
              map.put("现价", ftService.getPrice());
              map.put("是否上架：1.是，0.否", ftService.getPutShelf());
              map.put("是否参加活动：1.是，0.否", ftService.getActivityFlag());
              map.put("参加的活动", ftService.getActivityName());
              map.put("活动规则", ftService.getActivityRule());
              map.put("服务类型", ftService.getType());
              map.put("咨询人数", ftService.getAdvisoryNumber());
              map.put("联系电话", ftService.getContactNumber());
              map.put("服务所在城市", ftService.getServiceCity());
        list.add(map);
      }
      FileUtil.downloadExcel(list, response);
    }
}
